/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.marcelo.comun.database;

import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;

/**
 *
 * @author marcelo
 * 
 * La idea de esta clase es que pueda leer archivos en formato CSV, el decodificador esta seteado 
 * a mano ahora para UTF-8, pero la idea es cambiarlo, seria muy bueno leer la cantidad de lineas para
 * conocer cuanto falta, y calcular lo estimado de realizado
 * columnsName 
 * Buscar una solucion que permita conocer la cantidad de lineas que tiene el archivo?
 * 
 */
public class CSVReader {
   FileInputStream fileInputStream;
   BufferedReader bufferedReader;
   String caracterSeparacion = ",";
   HashMap<String, String> mapaDatos = new HashMap<String, String>();
   String[] columnsName;
   String[] values;
   Integer numLine;
   Integer numCol;
   Integer totalLines;
   String appVersion;
   
   /**
    * POr ahora 
    * @param file 
    */
    public CSVReader(File file ) throws FileNotFoundException, IOException{
        fileInputStream = new FileInputStream(file);    
        this.bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream, Charset.forName("UTF-8")));
//        contTotalLines();
    }
    
    public CSVReader(File file, String caracterSeparacion) throws FileNotFoundException, IOException{
        this(file);
        this.caracterSeparacion=caracterSeparacion;
    }

//    public CSVReader(BufferedReader br, String caracterSeparacion) throws IOException{
//        this.bufferedReader = br;
//        this.caracterSeparacion = caracterSeparacion;
//        contTotalLines();
//    }
    
    /**
     * Este metodo debe leer una linea llenar el hashMap para luego poder hacerder los datos desde el metodo
     * get
     * @return 
     */
    public boolean readRecord()throws IOException, IndexOutOfBoundsException{
        String line = bufferedReader.readLine();
        if (line != null) {
            numLine ++;
            values =  line.split(caracterSeparacion);
            //Meter los datos en el hashMap
            for (numCol=0; numCol<columnsName.length -1 ; numCol++) {
                //Chequear si tiene datos en esa posicion
                mapaDatos.put(columnsName[numCol].trim(), values[numCol].trim());
            }
            return true;
        }
        return false;
    }
    
    //Si no pudo leer el encabezadp retorna falso
    public boolean readHeaders() throws IOException{
        String line = bufferedReader.readLine();
        if (line != null){
            numLine = 0;
            //Leer datos
            String[] datos = line.split(caracterSeparacion);
            //Inicializar la version de la bbdd
            appVersion = datos[datos.length-1];
            columnsName = new String[datos.length - 1]; 
            //cargar los datos en la columna nombre de columnas
            for (int i=0; i<datos.length -1 ;i++){
                columnsName[i] = datos[i];
            }
            return true;
        }
        return false;
        //Meter los datos en el hashMap
        
        
    }
    
    public String get(String data) {
        if (mapaDatos.containsKey(data))
            return mapaDatos.get(data);
        else 
            return "";
    }
    
    public Integer getLine(){
        return numLine;
    }
    
    public Integer getColumn(){
        return numCol;
    }
    
    public void close() throws IOException{
        bufferedReader.close();
    }
    
    public String[] getColumnsName() {
        return columnsName;
    }
    
    public Integer getTotalLines() {
        return totalLines;
    }
    
    public String[] getValues() {
        return values;
    }
    
    //Calcula el total de las lineas en 
    private void contTotalLines() throws IOException {
        
        InputStream is = new BufferedInputStream(fileInputStream);
        byte[] byteBuff = new byte[1024];
        int count = 0;
        int readChars = 0;
        boolean empty = true;
        while ((readChars = is.read(byteBuff)) != -1) {
            empty = false;
            for (int i = 0; i < readChars; ++i) {
                if (byteBuff[i] == '\n')
                    ++count;
            }
        }
        totalLines = (count == 0 && !empty) ? 1 : count;
        is.close();
    }
}
